package model.skill;

import model.Executable;
import model.GameClock;
import model.effect.ConstantChangeStatEffect;
import model.effect.Effect;
import model.entity.stats.StatType;
import model.map.Direction;
import model.map.GameMap;
import model.map.HexLocationProjection;
import model.map.Location;
import model.map.LocationProjection;
import model.map.World;

/**
 * A propagation to return all the locations in a certain direction from the location within a certain range
 */
public class LinearProjectile extends Projectile {
	
	/**
	 * @param startLocation
	 * @param range
	 * @param direction
	 * @param propagationLogic
	 */
	private Location startLocation;
	private Location previous;
	private int counter;
	private Location mapLocation;
	private LinearProjectile linear = this;
	
	public LinearProjectile(String name, Effect effect, LocationProjection propagationLogic, int range, int speed)
	{
		super(name, effect, propagationLogic, range, speed);
	}

	public LinearProjectile() {
		// TODO Auto-generated constructor stub
	}

	public void propagate(ProjectileInformation projectileInfo)
	{	
		counter = super.getRange();
		startLocation = projectileInfo.getLocation();
		previous = new Location();
		mapLocation = null;
		
		final GameMap gameMap = World.getInstance().getCurrentMap();
		final GameClock c = GameClock.getInstance();
		final LocationProjection mySuper = this.getPropagationLogic();
		final int propagateSpeed = this.getSpeed();
		final Direction projectileDirection = projectileInfo.getDirection();
		
		Executable exec = new Executable()
		{
			public void execute() {
				
				if(gameMap.hasProjectile(mapLocation))
				{
					gameMap.removeProjectile(mapLocation);
				}
				
				startLocation = mySuper.projectLocation(startLocation, projectileDirection);
				if(previous.equals(startLocation))
					counter = 1;
				else
					;
				
				gameMap.addProjectile(startLocation, linear);
				if(gameMap.hasEntity(startLocation))
				{
					linear.getEffect().doEffect(gameMap.getEntity(startLocation));
				}
				
				previous = startLocation;
				mapLocation = previous;
				if(counter > 1) {
					--counter;
					c.schedule(propagateSpeed, this);
				}
				else
				{
					c.schedule(propagateSpeed, new Executable() {
						public void execute() 
						{	
							if(gameMap.hasProjectile(mapLocation))
								{
									gameMap.removeProjectile(mapLocation);
								}
						}
					});
				}
			}
		};
		exec.execute();
	}
}
